<?php

namespace app\server\tcp\controller;

use app\server\inter\WorkerDriver;
use app\server\model\{
    Config, ControlFilter, Db
};
use Workerman\Lib\Timer;
use Workerman\Worker;

/**
 * 远程控制器
 *
 * Class Control
 * @package app\server\tcp\controller
 */
class Control implements WorkerDriver
{

    private $worker;

    private $_listen;

    /**
     * Control constructor.
     */
    public function __construct()
    {
        $this->worker = new Worker(Config::get('control_server.tcp_host'));
        $this->worker->onWorkerStart = [$this, 'onWorkerStart'];
        $this->worker->onConnect = [$this, 'onConnect'];
        $this->worker->onMessage = [$this, 'onMessage'];
        $this->worker->onClose = [$this, 'onClose'];
        $this->worker->onError = [$this, 'onError'];
    }

    /**
     * 连接
     *
     * @param $connection
     */
    public function onConnect($connection)
    {
        $filter = new ControlFilter('tcp');
        $clientIp = $connection->getRemoteAddress();
        echo "ip------" . $clientIp . "------tcp in......\r\n";
        if ( ! $filter->checkClient($clientIp)) {
            echo "http:unauthorized \r\n";
            $connection->close('未授权的请求');
        }
    }

    /**
     * 开始进程
     *
     * @param $worker
     * @throws \Exception
     */
    public function onWorkerStart($worker)
    {

        // 开始主进程
        echo 'start main process' . PHP_EOL;

        /**
         * 实例数据库
         */
        if (Config::get('control_server.db')) {
            echo 'start mysql' . PHP_EOL;
            Db::instance();
        }

        /**
         * 子进程
         */
        $web = new Worker(Config::get('control_server.http_host'));

        /**
         * 子进程回调类
         */
        $this->_listen = new ControlHttp();
        $web->onConnect = [$this->_listen, 'onConnect'];
        $web->onMessage = [$this->_listen, 'onMessage'];
        $web->listen();

        /**
         * 计时器心跳
         */
        Timer::add(1, function () use ($worker) {
            $timeNow = time();
            foreach ($worker->connections as $connection) {
                // 有可能该connection还没收到过消息，则lastMessageTime设置为当前时间
                if (empty($connection->lastMessageTime)) {
                    $connection->lastMessageTime = $timeNow;
                    continue;
                }
                // 上次通讯时间间隔大于心跳间隔，则认为客户端已经下线，关闭连接
                if ($timeNow - $connection->lastMessageTime > Config::get('control_server.heartbeat')) {
                    $connection->close();
                }
            }
        });
    }

    /**
     * 接收消息回调
     *
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data)
    {
        echo "message......" . PHP_EOL;
        $macData = bin2hex($data);
        echo $macData . PHP_EOL;

        // 匹配设备号
        preg_match('/^fa(\d|\w){22}faff$/', $macData, $matches);
        // 匹配设备发过来的状态 AAAA 04 CC 03FF 34
        preg_match('/aaaa04cc(\d|\w){4}34$/', $macData, $matches2);
        if ( ! empty($matches)) {
            if ($this->_listen instanceof ControlHttp) {
                echo "push mac......\r\n";
                $this->_listen->tcpConnectObj[$macData] = $connection;
            }
        }

        if ( ! empty($matches2)) {
            // todo::获取设备数据待处理
            echo 'send' . PHP_EOL;
        }
        $connection->lastMessageTime = time();
    }

    /**
     * @param $connection
     */
    public function onBufferFull($connection)
    {
        // TODO: Implement onBufferFull() method.
    }

    /**
     * @param $connection
     */
    public function onBufferDrain($connection)
    {
        // TODO: Implement onBufferDrain() method.
    }

    /**
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
        echo "abort......\r\n";
        print_r($msg);
        echo "abort......\r\n";
    }

    /**
     * @param $connection
     */
    public function onClose($connection)
    {
        echo "out......\r\n";
    }
}